import Konva from "konva";
import { Draw } from "../../../Draw/Draw";
import { getColorMatch } from "../../../Utils";
import { IKonva } from "../../../Interface/IKonva";
import { TRANSFORMER_OPTION } from "../../../Config/transformer-options";

/**
 * Konva Graph 基类形变事件处理函数
 * @param draw
 * @param group 这里虽然传入的是 Group 但是监听缩放旋转的却是 group.children[0] 以避免文本的缩放
 * @returns
 */
export function setGroupTransformer(draw: Draw, group: Konva.Group) {
  const layer = draw.getLayer();
  if (!layer) return;

  const shape = group.children[0];

  group.setAttr("selected", true);

  // 创建新的形变节点
  const transformerColor = <string>getColorMatch(draw, "transformerColor");

  const tr = new Konva.Transformer({
    ...TRANSFORMER_OPTION,
    anchorStroke: transformerColor,
    anchorFill: transformerColor,
    borderStroke: transformerColor,
  });

  layer.add(tr.nodes([shape]));
  layer.draw(); // 添加形变节点不需要缓存，因此不需要调用 draw.render()

  // shape.on("transformstart", transformStart);
  shape.on("transform", transformHandle);
  shape.on("transformend", (e) => transformEndHandle(e, draw));
}

/**
 * 缩放过程中，需要实时修改文本的宽高，以达到自适应效果
 * 同时，旋转过程中，文本也要跟着旋转
 * 形变过程，需要强制刷新形变节点
 * @param e
 */
function transformHandle(e: IKonva.Event) {
  // 获取实际的宽高
  const scaleX = e.target.scaleX();
  const scaleY = e.target.scaleY();

  const width = e.target.width() * scaleX;
  const height = e.target.height() * scaleY;
  const group = <Konva.Group>e.target.parent;

  group.setAttrs({ realWidth: width, realHeight: height });

  const text = group.findOne("Text");
  if (!text) return;

  text.width(width);
  text.height(height);

  // 处理旋转
  const { rotation, x, y } = e.currentTarget.attrs;
  // 旋转过程中 x y 会跟着变，因此，直接增加 父元素相同的偏移量即可
  text.setAttrs({ rotation, x, y });
}

/**
 * 形变结束事件处理函数
 */
function transformEndHandle(e: IKonva.Event, draw: Draw) {
  draw.render();

  // 获取真实的缩放比例
  const shape = e.currentTarget; // currentTarget指向监听事件的对象 Group.children[0]

  const { scaleX, scaleY, rotation, x, y } = shape.attrs;

  const group = <Konva.Group>shape.parent;
  /**
   * 收到广播后，需要做几件事：
   *  1. 修改真实的 shape 属性；
   *  2. 添加 Group 的属性 realWidth realHeight (因为 Group 的宽高是经过形变后，需要还原)
   *  3. 修正 Text 属性， text.setAttrs({ rotation, x, y }); 可参考 transformHandle 处理过程
   */
  // 广播形变结束事件
  draw.broadcast({
    type: `${group.id()}_transformEnd`,
    payload: {
      layerID: draw.getLayer()?.id(),
      groupID: group.id(),
      rotation,
      scaleX,
      scaleY,
      x,
      y,
    },
  });
}
